#ifndef GMACHINE_HEADER_GFUNCTION_H
#define GMACHINE_HEADER_GFUNCTION_H

#include "GStacker.h"
#include "GRegister.h"

namespace GMachine
{
	/////////////////////////////////////////////////////////////////////
	// Class: ClassObject
	/////////////////////////////////////////////////////////////////////
	class ClassObject
	{
	public:
		ClassObject(HandleObject*(*c)(), void(*d)(HandleObject*)):constructor(c), destructor(d) { return; }
		ClassObject(const ClassObject& rhs):constructor(rhs.constructor), destructor(rhs.destructor) { return; }
	public:
		ClassObject& operator=(const ClassObject& rhs)
		{
			if (this != &rhs)
			{
				this->constructor	=	rhs.constructor;
				this->destructor	=	rhs.destructor;
			}
			return *this;
		}
	public:
		HandleObject * Create() const {  return constructor(); }
		void Delete(HandleObject * obj) const { destructor(obj); }
	private:
		HandleObject * (*constructor)(); void (*destructor)(HandleObject *);
	};

	/////////////////////////////////////////////////////////////////////
	// Template: ExportClass
	// Inherited from ClassObject.
	/////////////////////////////////////////////////////////////////////
	template<typename T> class ExportClass:public ClassObject 
	{
	private:
		static HandleObject * Constructor()	{ return (HandleObject*)(new T()); }
		static void Destructor(HandleObject * obj) { delete (T*)(obj); }
	public:
		ExportClass<T>():ClassObject(ExportClass<T>::Constructor, ExportClass<T>::Destructor){ return; }
	};


	/////////////////////////////////////////////////////////////////////
	// Class: FunctionObject
	/////////////////////////////////////////////////////////////////////
	class FunctionObject
	{
	public:
		FunctionObject(void (*c)(void *, GStacker&, GRegister&), void * f):caller(c), callee(f) { return; }
		FunctionObject(const FunctionObject& rhs):caller(rhs.caller), callee(rhs.callee) { return; }
	public:
		FunctionObject& operator=(const FunctionObject& rhs)
		{
			if (this != &rhs)
			{
				this->caller = rhs.caller;
				this->callee = rhs.callee;
			}
			return *this;
		}
	public:
		void Invoke(GStacker & stk, GRegister & reg) const
		{
			caller(callee, stk, reg);
		}
	private:
		void (*caller)(void *, GStacker &, GRegister &); void * callee;
	};
	
	
	/////////////////////////////////////////////////////////////////////
	// Template Function: Objectval
	/////////////////////////////////////////////////////////////////////
	template<typename T> struct Objectval
	{
		static inline T* Read(GRegister& reg, U8 *& frame)
		{
			return (T*)(PickHandle(reg, frame));
		}
	//	static inline bool Write(GStacker&, T*);
	};

	/////////////////////////////////////////////////////////////////////
	// Template Function: Returnval
	/////////////////////////////////////////////////////////////////////
	template<typename T> struct Returnval
	{
		static inline T* Read(GRegister& reg, U8 *& frame)
		{
			return (T*)(PickHandle(reg, frame));
		}
	};

	template<typename T> struct Returnval<T&>
	{
		static inline T* Read(GRegister& reg, U8 *& frame)
		{
			return (T*)(PickHandle(reg, frame));
		}
	};

#	define SPECITYMETHOD(method, type, ret)						\
	template<> struct Returnval<type>							\
	{															\
		static inline ret * Read(GRegister& reg, U8 *& frame)	\
		{														\
			return method(reg, frame);							\
		}														\
	}

	SPECITYMETHOD(PickFloating, float, FloatingObject);
	SPECITYMETHOD(PickFloating, double, FloatingObject);
	SPECITYMETHOD(PickFloating, long double, FloatingObject);
	SPECITYMETHOD(PickInteger, bool, IntegerObject);
	SPECITYMETHOD(PickInteger, char, IntegerObject);
	SPECITYMETHOD(PickInteger, signed char, IntegerObject);
	SPECITYMETHOD(PickInteger, unsigned char, IntegerObject);
	SPECITYMETHOD(PickInteger, int, IntegerObject);
	SPECITYMETHOD(PickInteger, short int, IntegerObject);
	SPECITYMETHOD(PickInteger, long int, IntegerObject);
	SPECITYMETHOD(PickInteger, unsigned int, IntegerObject);
	SPECITYMETHOD(PickInteger, unsigned short int, IntegerObject);
	SPECITYMETHOD(PickInteger, unsigned long int, IntegerObject);
#	if defined(SUPPORT_wchar_t)
	SPECITYMETHOD(PickInteger, wchar_t, IntegerObject);
#	endif
#	if defined(SUPPORT_long_long_int)
	SPECITYMETHOD(PickInteger, long long int, IntegerObject);
	SPECITYMETHOD(PickInteger, unsigned long long int, IntegerObject);
#	endif
#	undef  SPECITYMETHOD

	/////////////////////////////////////////////////////////////////////
	// Template Function: Parameter
	/////////////////////////////////////////////////////////////////////
	template<typename T> struct Parameter
	{
		static inline T Read(GRegister& reg, U8 *& frame)
		{
			return (*(T*)PickHandle(reg, frame));
		}
	};

	template<typename T> struct Parameter<T&>
	{
		static inline T& Read(GRegister& reg, U8 *& frame)
		{
			return (T&)(**(T**)PickHandle(reg, frame));
		}
	};

	template<> struct Parameter<bool>
	{
		static inline bool Read(GRegister& reg, U8 *& frame)
		{
			return (*PickInteger(reg, frame) != 0);
		}
	};

#	define SPECITYMETHOD(method, type)							\
	template<> struct Parameter< type >							\
	{															\
		static inline type Read(GRegister& reg, U8 *& frame)	\
		{														\
			return type(*method(reg, frame));					\
		}														\
	}

	SPECITYMETHOD(PickFloating, float);
	SPECITYMETHOD(PickFloating, double);
	SPECITYMETHOD(PickFloating, long double);
	SPECITYMETHOD(PickInteger, char);
	SPECITYMETHOD(PickInteger, signed char);
	SPECITYMETHOD(PickInteger, unsigned char);
	SPECITYMETHOD(PickInteger, int);
	SPECITYMETHOD(PickInteger, short int);
	SPECITYMETHOD(PickInteger, long int);
	SPECITYMETHOD(PickInteger, unsigned int);
	SPECITYMETHOD(PickInteger, unsigned short int);
	SPECITYMETHOD(PickInteger, unsigned long int);
#	if defined(SUPPORT_wchar_t)
	SPECITYMETHOD(PickInteger, wchar_t);
#	endif
#	if defined(SUPPORT_long_long_int)
	SPECITYMETHOD(PickInteger, long long int);
	SPECITYMETHOD(PickInteger, unsigned long long int);
#	endif
#	undef  SPECITYMETHOD


	/////////////////////////////////////////////////////////////////////
	// Template: ExportFunction, for member functions.
	// Return: FunctionObject
	/////////////////////////////////////////////////////////////////////
	namespace ImplMemberFunctionCaller
	{
		//--------------------------------------------------------------------------
		// 16 params, have a return value.
		template<typename TRET, typename TCLASS, 
			typename P1 = void, typename P2 = void, typename P3 = void, typename P4 = void, 
			typename P5 = void, typename P6 = void, typename P7 = void, typename P8 = void,
			typename P9 = void, typename P10= void, typename P11= void, typename P12= void,
			typename P13= void, typename P14= void, typename P15= void, typename P16= void>
		struct Caller
		{
			static inline void Invoke(void * callee, GStacker& stk, GRegister& reg) 
			{
				TRET(TCLASS::*method)(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16)
					= *(TRET(TCLASS::**)(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16))(&callee);
				U8 * frame = stk.CurrentFrame();
				*(Returnval<TRET>::Read(reg, frame)) = (Objectval<TCLASS>::Read(reg, frame)->*method)(
					Parameter<P1>::Read(reg, frame), Parameter<P2>::Read(reg, frame),
					Parameter<P3>::Read(reg, frame), Parameter<P4>::Read(reg, frame),
					Parameter<P5>::Read(reg, frame), Parameter<P6>::Read(reg, frame),
					Parameter<P7>::Read(reg, frame), Parameter<P8>::Read(reg, frame),
					Parameter<P9>::Read(reg, frame), Parameter<P10>::Read(reg, frame),
					Parameter<P11>::Read(reg, frame),Parameter<P12>::Read(reg, frame),
					Parameter<P13>::Read(reg, frame),Parameter<P14>::Read(reg, frame),
					Parameter<P15>::Read(reg, frame),Parameter<P16>::Read(reg, frame));
				return;
			}
		};

		// 16 params, no return value.
		template<typename TCLASS, 
			typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8,
			typename P9, typename P10,typename P11,typename P12,typename P13,typename P14,typename P15,typename P16>
		struct Caller<void, TCLASS, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16>
		{
			static inline void Invoke(void * callee, GStacker& stk, GRegister& reg) 
			{
				void(TCLASS::*method)(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16) 
					= *(void(TCLASS::**)(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16))(&callee);
				U8 * frame = stk.CurrentFrame();
				Objectval<TCLASS>::Read(reg, frame)->*method( 
					Parameter<P1>::Read(reg, frame), Parameter<P2>::Read(reg, frame),
					Parameter<P3>::Read(reg, frame), Parameter<P4>::Read(reg, frame),
					Parameter<P5>::Read(reg, frame), Parameter<P6>::Read(reg, frame),
					Parameter<P7>::Read(reg, frame), Parameter<P8>::Read(reg, frame),
					Parameter<P9>::Read(reg, frame), Parameter<P10>::Read(reg, frame),
					Parameter<P11>::Read(reg, frame),Parameter<P12>::Read(reg, frame),
					Parameter<P13>::Read(reg, frame),Parameter<P14>::Read(reg, frame),
					Parameter<P15>::Read(reg, frame),Parameter<P16>::Read(reg, frame));
				return;
			}
		};
		//--------------------------------------------------------------------------
		// 15 params, have a return value.
		template<typename TRET, typename TCLASS, 
			typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8,
			typename P9, typename P10,typename P11,typename P12,typename P13,typename P14,typename P15>
		struct Caller<TRET, TCLASS, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, void>
		{
			static inline void Invoke(void * callee, GStacker& stk, GRegister& reg) 
			{
				TRET(TCLASS::*method)(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15) 
					= *(TRET(TCLASS::**)(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15))(&callee);
				U8 * frame = stk.CurrentFrame();
				*(Returnval<TRET>::Read(reg, frame)) = (Objectval<TCLASS>::Read(reg, frame)->*method)( 
					Parameter<P1>::Read(reg, frame), Parameter<P2>::Read(reg, frame),
					Parameter<P3>::Read(reg, frame), Parameter<P4>::Read(reg, frame),
					Parameter<P5>::Read(reg, frame), Parameter<P6>::Read(reg, frame),
					Parameter<P7>::Read(reg, frame), Parameter<P8>::Read(reg, frame),
					Parameter<P9>::Read(reg, frame), Parameter<P10>::Read(reg, frame),
					Parameter<P11>::Read(reg, frame),Parameter<P12>::Read(reg, frame),
					Parameter<P13>::Read(reg, frame),Parameter<P14>::Read(reg, frame),
					Parameter<P15>::Read(reg, frame));	
				return;
			}
		};
		// 15 params, no return value.
		template<typename TCLASS, 
			typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8,
			typename P9, typename P10,typename P11,typename P12,typename P13,typename P14,typename P15>
		struct Caller<void, TCLASS, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, void>
		{
			static inline void Invoke(void * callee, GStacker& stk, GRegister& reg) 
			{
				void(TCLASS::*method)(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15) 
					= *(void(TCLASS::**)(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15))(&callee);
				U8 * frame = stk.CurrentFrame();
				Objectval<TCLASS>::Read(reg, frame)->*method( 
					Parameter<P1>::Read(reg, frame), Parameter<P2>::Read(reg, frame),
					Parameter<P3>::Read(reg, frame), Parameter<P4>::Read(reg, frame),
					Parameter<P5>::Read(reg, frame), Parameter<P6>::Read(reg, frame),
					Parameter<P7>::Read(reg, frame), Parameter<P8>::Read(reg, frame),
					Parameter<P9>::Read(reg, frame), Parameter<P10>::Read(reg, frame),
					Parameter<P11>::Read(reg, frame),Parameter<P12>::Read(reg, frame),
					Parameter<P13>::Read(reg, frame),Parameter<P14>::Read(reg, frame),
					Parameter<P15>::Read(reg, frame));	
				return;
			}
		};
		//--------------------------------------------------------------------------
		// 14 params, have a return value.
		template<typename TRET, typename TCLASS, 
			typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8,
			typename P9, typename P10,typename P11,typename P12,typename P13,typename P14>
		struct Caller<TRET, TCLASS, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, void, void>
		{
			static inline void Invoke(void * callee, GStacker& stk, GRegister& reg) 
			{
				TRET(TCLASS::*method)(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14) 
					= *(TRET(TCLASS::**)(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14))(&callee);
				U8 * frame = stk.CurrentFrame();
				*(Returnval<TRET>::Read(reg, frame)) = (Objectval<TCLASS>::Read(reg, frame)->*method)( 
					Parameter<P1>::Read(reg, frame), Parameter<P2>::Read(reg, frame),
					Parameter<P3>::Read(reg, frame), Parameter<P4>::Read(reg, frame),
					Parameter<P5>::Read(reg, frame), Parameter<P6>::Read(reg, frame),
					Parameter<P7>::Read(reg, frame), Parameter<P8>::Read(reg, frame),
					Parameter<P9>::Read(reg, frame), Parameter<P10>::Read(reg, frame),
					Parameter<P11>::Read(reg, frame),Parameter<P12>::Read(reg, frame),
					Parameter<P13>::Read(reg, frame),Parameter<P14>::Read(reg, frame));	
				return;
			}
		};
		// 14 params, no return value.
		template<typename TCLASS, 
			typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8,
			typename P9, typename P10,typename P11,typename P12,typename P13,typename P14>
		struct Caller<void, TCLASS, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, void, void>
		{
			static inline void Invoke(void * callee, GStacker& stk, GRegister& reg) 
			{
				void(TCLASS::*method)(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14) 
					= *(void(TCLASS::**)(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14))(&callee);
				U8 * frame = stk.CurrentFrame();
				Objectval<TCLASS>::Read(reg, frame)->*method( 
					Parameter<P1>::Read(reg, frame), Parameter<P2>::Read(reg, frame),
					Parameter<P3>::Read(reg, frame), Parameter<P4>::Read(reg, frame),
					Parameter<P5>::Read(reg, frame), Parameter<P6>::Read(reg, frame),
					Parameter<P7>::Read(reg, frame), Parameter<P8>::Read(reg, frame),
					Parameter<P9>::Read(reg, frame), Parameter<P10>::Read(reg, frame),
					Parameter<P11>::Read(reg, frame),Parameter<P12>::Read(reg, frame),
					Parameter<P13>::Read(reg, frame),Parameter<P14>::Read(reg, frame));	
				return;
			}
		};
		//--------------------------------------------------------------------------
		// 13 params, have a return value.
		template<typename TRET, typename TCLASS, 
			typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8,
			typename P9, typename P10,typename P11,typename P12,typename P13>
		struct Caller<TRET, TCLASS, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, void, void, void>
		{
			static inline void Invoke(void * callee, GStacker& stk, GRegister& reg) 
			{
				TRET(TCLASS::*method)(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13) 
					= *(TRET(TCLASS::**)(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13))(&callee);
				U8 * frame = stk.CurrentFrame();
				*(Returnval<TRET>::Read(reg, frame)) = (Objectval<TCLASS>::Read(reg, frame)->*method)( 
					Parameter<P1>::Read(reg, frame), Parameter<P2>::Read(reg, frame),
					Parameter<P3>::Read(reg, frame), Parameter<P4>::Read(reg, frame),
					Parameter<P5>::Read(reg, frame), Parameter<P6>::Read(reg, frame),
					Parameter<P7>::Read(reg, frame), Parameter<P8>::Read(reg, frame),
					Parameter<P9>::Read(reg, frame), Parameter<P10>::Read(reg, frame),
					Parameter<P11>::Read(reg, frame),Parameter<P12>::Read(reg, frame),
					Parameter<P13>::Read(reg, frame));	
				return;
			}
		};
		// 13 params, no return value.
		template<typename TCLASS, 
			typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8,
			typename P9, typename P10,typename P11,typename P12,typename P13>
		struct Caller<void, TCLASS, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, void, void, void>
		{
			static inline void Invoke(void * callee, GStacker& stk, GRegister& reg) 
			{
				void(TCLASS::*method)(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13) 
					= *(void(TCLASS::**)(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13))(&callee);
				U8 * frame = stk.CurrentFrame();
				Objectval<TCLASS>::Read(reg, frame)->*method( 
					Parameter<P1>::Read(reg, frame), Parameter<P2>::Read(reg, frame),
					Parameter<P3>::Read(reg, frame), Parameter<P4>::Read(reg, frame),
					Parameter<P5>::Read(reg, frame), Parameter<P6>::Read(reg, frame),
					Parameter<P7>::Read(reg, frame), Parameter<P8>::Read(reg, frame),
					Parameter<P9>::Read(reg, frame), Parameter<P10>::Read(reg, frame),
					Parameter<P11>::Read(reg, frame),Parameter<P12>::Read(reg, frame),
					Parameter<P13>::Read(reg, frame));	
				return;
			}
		};

		//--------------------------------------------------------------------------
		// 12 params, have a return value.
		template<typename TRET, typename TCLASS, 
			typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8,
			typename P9, typename P10,typename P11,typename P12>
		struct Caller<TRET, TCLASS, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, void, void, void, void>
		{
			static inline void Invoke(void * callee, GStacker& stk, GRegister& reg) 
			{
				TRET(TCLASS::*method)(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12) 
					= *(TRET(TCLASS::**)(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12))(&callee);
				U8 * frame = stk.CurrentFrame();
				*(Returnval<TRET>::Read(reg, frame)) = (Objectval<TCLASS>::Read(reg, frame)->*method)(
					Parameter<P1>::Read(reg, frame), Parameter<P2>::Read(reg, frame),
					Parameter<P3>::Read(reg, frame), Parameter<P4>::Read(reg, frame),
					Parameter<P5>::Read(reg, frame), Parameter<P6>::Read(reg, frame),
					Parameter<P7>::Read(reg, frame), Parameter<P8>::Read(reg, frame),
					Parameter<P9>::Read(reg, frame), Parameter<P10>::Read(reg, frame),
					Parameter<P11>::Read(reg, frame),Parameter<P12>::Read(reg, frame));
				return;
			}
		};
		// 12 params, no return value.
		template<typename TCLASS, 
			typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8,
			typename P9, typename P10,typename P11,typename P12>
		struct Caller<void, TCLASS, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, void, void, void, void>
		{
			static inline void Invoke(void * callee, GStacker& stk, GRegister& reg) 
			{
				void(TCLASS::*method)(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12) 
					= *(void(TCLASS::**)(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12))(&callee);
				U8 * frame = stk.CurrentFrame();
				Objectval<TCLASS>::Read(reg, frame)->*method( 
					Parameter<P1>::Read(reg, frame), Parameter<P2>::Read(reg, frame),
					Parameter<P3>::Read(reg, frame), Parameter<P4>::Read(reg, frame),
					Parameter<P5>::Read(reg, frame), Parameter<P6>::Read(reg, frame),
					Parameter<P7>::Read(reg, frame), Parameter<P8>::Read(reg, frame),
					Parameter<P9>::Read(reg, frame), Parameter<P10>::Read(reg, frame),
					Parameter<P11>::Read(reg, frame),Parameter<P12>::Read(reg, frame));	
				return;
			}
		};

		//--------------------------------------------------------------------------
		// 11 params, have a return value.
		template<typename TRET, typename TCLASS, 
			typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8,
			typename P9, typename P10,typename P11>
		struct Caller<TRET, TCLASS, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, void, void, void, void, void>
		{
			static inline void Invoke(void * callee, GStacker& stk, GRegister& reg) 
			{
				TRET(TCLASS::*method)(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11) 
					= *(TRET(TCLASS::**)(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11))(&callee);
				U8 * frame = stk.CurrentFrame();
				*(Returnval<TRET>::Read(reg, frame)) = (Objectval<TCLASS>::Read(reg, frame)->*method)(
					Parameter<P1>::Read(reg, frame), Parameter<P2>::Read(reg, frame),
					Parameter<P3>::Read(reg, frame), Parameter<P4>::Read(reg, frame),
					Parameter<P5>::Read(reg, frame), Parameter<P6>::Read(reg, frame),
					Parameter<P7>::Read(reg, frame), Parameter<P8>::Read(reg, frame),
					Parameter<P9>::Read(reg, frame), Parameter<P10>::Read(reg, frame),
					Parameter<P11>::Read(reg, frame));
				return;
			}
		};
		// 11 params, no return value.
		template<typename TCLASS,
			typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8,
			typename P9, typename P10,typename P11>
		struct Caller<void, TCLASS, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, void, void, void, void, void>
		{
			static inline void Invoke(void * callee, GStacker& stk, GRegister& reg) 
			{
				void(TCLASS::*method)(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11) 
					= *(void(TCLASS::**)(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11))(&callee);
				U8 * frame = stk.CurrentFrame();
				Objectval<TCLASS>::Read(reg, frame)->*method( 
					Parameter<P1>::Read(reg, frame), Parameter<P2>::Read(reg, frame),
					Parameter<P3>::Read(reg, frame), Parameter<P4>::Read(reg, frame),
					Parameter<P5>::Read(reg, frame), Parameter<P6>::Read(reg, frame),
					Parameter<P7>::Read(reg, frame), Parameter<P8>::Read(reg, frame),
					Parameter<P9>::Read(reg, frame), Parameter<P10>::Read(reg, frame),
					Parameter<P11>::Read(reg, frame));	
				return;
			}
		};
		//--------------------------------------------------------------------------
		// 10 params, have a return value.
		template<typename TRET, typename TCLASS, 
			typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8,
			typename P9, typename P10>
		struct Caller<TRET, TCLASS, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, void, void, void, void, void, void>
		{
			static inline void Invoke(void * callee, GStacker& stk, GRegister& reg) 
			{
				TRET(TCLASS::*method)(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10) 
					= *(TRET(TCLASS::**)(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10))(&callee);
				U8 * frame = stk.CurrentFrame();
				*(Returnval<TRET>::Read(reg, frame)) = (Objectval<TCLASS>::Read(reg, frame)->*method)(
					Parameter<P1>::Read(reg, frame), Parameter<P2>::Read(reg, frame),
					Parameter<P3>::Read(reg, frame), Parameter<P4>::Read(reg, frame),
					Parameter<P5>::Read(reg, frame), Parameter<P6>::Read(reg, frame),
					Parameter<P7>::Read(reg, frame), Parameter<P8>::Read(reg, frame),
					Parameter<P9>::Read(reg, frame), Parameter<P10>::Read(reg, frame));
				return;
			}
		};
		// 10 params, no return value.
		template<typename TCLASS,
			typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8,
			typename P9, typename P10>
		struct Caller<void, TCLASS, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, void, void, void, void, void, void>
		{
			static inline void Invoke(void * callee, GStacker& stk, GRegister& reg) 
			{
				void(TCLASS::*method)(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10) 
					= *(void(TCLASS::**)(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10))(&callee);
				U8 * frame = stk.CurrentFrame();
				Objectval<TCLASS>::Read(reg, frame)->*method( 
					Parameter<P1>::Read(reg, frame), Parameter<P2>::Read(reg, frame),
					Parameter<P3>::Read(reg, frame), Parameter<P4>::Read(reg, frame),
					Parameter<P5>::Read(reg, frame), Parameter<P6>::Read(reg, frame),
					Parameter<P7>::Read(reg, frame), Parameter<P8>::Read(reg, frame),
					Parameter<P9>::Read(reg, frame), Parameter<P10>::Read(reg, frame));
				return;
			}
		};

		//--------------------------------------------------------------------------
		// 9 params, have a return value.
		template<typename TRET, typename TCLASS, 
			typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8,
			typename P9>
		struct Caller<TRET, TCLASS, P1, P2, P3, P4, P5, P6, P7, P8, P9, void, void, void, void, void, void, void>
		{
			static inline void Invoke(void * callee, GStacker& stk, GRegister& reg)
			{
				TRET(TCLASS::*method)(P1, P2, P3, P4, P5, P6, P7, P8, P9) 
					= *(TRET(TCLASS::**)(P1, P2, P3, P4, P5, P6, P7, P8, P9))(&callee);
				U8 * frame = stk.CurrentFrame();
				*(Returnval<TRET>::Read(reg, frame)) = (Objectval<TCLASS>::Read(reg, frame)->*method)(
					Parameter<P1>::Read(reg, frame), Parameter<P2>::Read(reg, frame),
					Parameter<P3>::Read(reg, frame), Parameter<P4>::Read(reg, frame),
					Parameter<P5>::Read(reg, frame), Parameter<P6>::Read(reg, frame),
					Parameter<P7>::Read(reg, frame), Parameter<P8>::Read(reg, frame),
					Parameter<P9>::Read(reg, frame));
				return;
			}
		};
		// 9 params, no return value.
		template<typename TCLASS, 
			typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8,
			typename P9>
		struct Caller<void, TCLASS, P1, P2, P3, P4, P5, P6, P7, P8, P9, void, void, void, void, void, void, void>
		{
			static inline void Invoke(void * callee, GStacker& stk, GRegister& reg)
			{
				void(TCLASS::*method)(P1, P2, P3, P4, P5, P6, P7, P8, P9)
					= *(void(TCLASS::**)(P1, P2, P3, P4, P5, P6, P7, P8, P9))(&callee);
				U8 * frame = stk.CurrentFrame();
				Objectval<TCLASS>::Read(reg, frame)->*method( 
					Parameter<P1>::Read(reg, frame), Parameter<P2>::Read(reg, frame),
					Parameter<P3>::Read(reg, frame), Parameter<P4>::Read(reg, frame),
					Parameter<P5>::Read(reg, frame), Parameter<P6>::Read(reg, frame),
					Parameter<P7>::Read(reg, frame), Parameter<P8>::Read(reg, frame),
					Parameter<P9>::Read(reg, frame));	
				return;
			}
		};

		//--------------------------------------------------------------------------
		// 8 params, have a return value.
		template<typename TRET, typename TCLASS, 
			typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8>
		struct Caller<TRET, TCLASS, P1, P2, P3, P4, P5, P6, P7, P8, void, void, void, void, void, void, void, void>
		{
			static inline void Invoke(void * callee, GStacker& stk, GRegister& reg) 
			{
				TRET(TCLASS::*method)(P1, P2, P3, P4, P5, P6, P7, P8) = *(TRET(TCLASS::**)(P1, P2, P3, P4, P5, P6, P7, P8))(&callee);
				U8 * frame = stk.CurrentFrame();
				*(Returnval<TRET>::Read(reg, frame)) = (Objectval<TCLASS>::Read(reg, frame)->*method)(
					Parameter<P1>::Read(reg, frame), Parameter<P2>::Read(reg, frame),
					Parameter<P3>::Read(reg, frame), Parameter<P4>::Read(reg, frame),
					Parameter<P5>::Read(reg, frame), Parameter<P6>::Read(reg, frame),
					Parameter<P7>::Read(reg, frame), Parameter<P8>::Read(reg, frame));
				return;
			}
		};
		// 8 params, no return value.
		template<typename TCLASS, 
			typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8>
		struct Caller<void, TCLASS, P1, P2, P3, P4, P5, P6, P7, P8, void, void, void, void, void, void, void, void>
		{
			static inline void Invoke(void * callee, GStacker& stk, GRegister& reg) 
			{
				void(TCLASS::*method)(P1, P2, P3, P4, P5, P6, P7, P8) = *(void(TCLASS::**)(P1, P2, P3, P4, P5, P6, P7, P8))(&callee);
				U8 * frame = stk.CurrentFrame();
				Objectval<TCLASS>::Read(reg, frame)->*method( 
					Parameter<P1>::Read(reg, frame), Parameter<P2>::Read(reg, frame),
					Parameter<P3>::Read(reg, frame), Parameter<P4>::Read(reg, frame),
					Parameter<P5>::Read(reg, frame), Parameter<P6>::Read(reg, frame),
					Parameter<P7>::Read(reg, frame), Parameter<P8>::Read(reg, frame));
				return;
			}
		};

		//--------------------------------------------------------------------------
		// 7 params, have a return value.
		template<typename TRET, typename TCLASS, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7>
		struct Caller<TRET, TCLASS, P1, P2, P3, P4, P5, P6, P7, void, void, void, void, void, void, void, void, void>
		{
			static inline void Invoke(void * callee, GStacker& stk, GRegister& reg) 
			{
				TRET(TCLASS::*method)(P1, P2, P3, P4, P5, P6, P7) = *(TRET(TCLASS::**)(P1, P2, P3, P4, P5, P6, P7))(&callee);
				U8 * frame = stk.CurrentFrame();
				*(Returnval<TRET>::Read(reg, frame)) = (Objectval<TCLASS>::Read(reg, frame)->*method)( 
					Parameter<P1>::Read(reg, frame), Parameter<P2>::Read(reg, frame),
					Parameter<P3>::Read(reg, frame), Parameter<P4>::Read(reg, frame),
					Parameter<P5>::Read(reg, frame), Parameter<P6>::Read(reg, frame),
					Parameter<P7>::Read(reg, frame));	
				return;
			}
		};		
		// 7 params, no return value.
		template<typename TCLASS, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7>
		struct Caller<void, TCLASS, P1, P2, P3, P4, P5, P6, P7, void, void, void, void, void, void, void, void, void>
		{
			static inline void Invoke(void * callee, GStacker& stk, GRegister& reg)
			{
				void(TCLASS::*method)(P1, P2, P3, P4, P5, P6, P7) = *(void(TCLASS::**)(P1, P2, P3, P4, P5, P6, P7))(&callee);
				U8 * frame = stk.CurrentFrame();
				Objectval<TCLASS>::Read(reg, frame)->*method( 
					Parameter<P1>::Read(reg, frame), Parameter<P2>::Read(reg, frame),
					Parameter<P3>::Read(reg, frame), Parameter<P4>::Read(reg, frame),
					Parameter<P5>::Read(reg, frame), Parameter<P6>::Read(reg, frame),
					Parameter<P7>::Read(reg, frame));	
				return;
			}
		};

		//--------------------------------------------------------------------------
		// 6 params, have a return value.
		template<typename TRET, typename TCLASS, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6>
		struct Caller<TRET, TCLASS, P1, P2, P3, P4, P5, P6, void, void, void, void, void, void, void, void, void, void>
		{
			static inline void Invoke(void * callee, GStacker& stk, GRegister& reg) 
			{
				TRET(TCLASS::*method)(P1, P2, P3, P4, P5, P6) = *(TRET(TCLASS::**)(P1, P2, P3, P4, P5, P6))(&callee);
				U8 * frame = stk.CurrentFrame();
				*(Returnval<TRET>::Read(reg, frame)) = (Objectval<TCLASS>::Read(reg, frame)->*method)( 
					Parameter<P1>::Read(reg, frame), Parameter<P2>::Read(reg, frame),
					Parameter<P3>::Read(reg, frame), Parameter<P4>::Read(reg, frame),
					Parameter<P5>::Read(reg, frame), Parameter<P6>::Read(reg, frame));
				return;
			}
		};
		// 6 params, no return value.
		template<typename TCLASS, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6>
		struct Caller<void, TCLASS, P1, P2, P3, P4, P5, P6, void, void, void, void, void, void, void, void, void, void>
		{
			static inline void Invoke(void * callee, GStacker& stk, GRegister& reg) 
			{
				void(TCLASS::*method)(P1, P2, P3, P4, P5, P6) = *(void(TCLASS::**)(P1, P2, P3, P4, P5, P6))(&callee);
				U8 * frame = stk.CurrentFrame();
				Objectval<TCLASS>::Read(reg, frame)->*method( 
					Parameter<P1>::Read(reg, frame), Parameter<P2>::Read(reg, frame),
					Parameter<P3>::Read(reg, frame), Parameter<P4>::Read(reg, frame),
					Parameter<P5>::Read(reg, frame), Parameter<P6>::Read(reg, frame));
				return;
			}
		};

		//--------------------------------------------------------------------------
		// 5 params, have a return value.
		template<typename TRET, typename TCLASS, typename P1, typename P2, typename P3, typename P4, typename P5>
		struct Caller<TRET, TCLASS, P1, P2, P3, P4, P5, void, void, void, void, void, void, void, void, void, void, void>
		{
			static inline void Invoke(void * callee, GStacker& stk, GRegister& reg) 
			{
				TRET(TCLASS::*method)(P1, P2, P3, P4, P5) = *(TRET(TCLASS::**)(P1, P2, P3, P4, P5))(&callee);
				U8 * frame = stk.CurrentFrame();
				*(Returnval<TRET>::Read(reg, frame)) = (Objectval<TCLASS>::Read(reg, frame)->*method)( 
					Parameter<P1>::Read(reg, frame), Parameter<P2>::Read(reg, frame),
					Parameter<P3>::Read(reg, frame), Parameter<P4>::Read(reg, frame),
					Parameter<P5>::Read(reg, frame));
				return;
			}
		};
		// 5 params, no return value.
		template<typename TCLASS, typename P1, typename P2, typename P3, typename P4, typename P5>
		struct Caller<void, TCLASS, P1, P2, P3, P4, P5, void, void, void, void, void, void, void, void, void, void, void>
		{
			static inline void Invoke(void * callee, GStacker& stk, GRegister& reg) 
			{
				void(TCLASS::*method)(P1, P2, P3, P4, P5) = *(void(TCLASS::**)(P1, P2, P3, P4, P5))(&callee);
				U8 * frame = stk.CurrentFrame();
				Objectval<TCLASS>::Read(reg, frame)->*method(
					Parameter<P1>::Read(reg, frame), Parameter<P2>::Read(reg, frame),
					Parameter<P3>::Read(reg, frame), Parameter<P4>::Read(reg, frame),
					Parameter<P5>::Read(reg, frame));
				return;
			}
		};

		//--------------------------------------------------------------------------
		// 4 params, have a return value.
		template<typename TRET, typename TCLASS, typename P1, typename P2, typename P3, typename P4>
		struct Caller<TRET, TCLASS, P1, P2, P3, P4, void, void, void, void, void, void, void, void, void, void, void, void>
		{
			static inline void Invoke(void * callee, GStacker& stk, GRegister& reg) 
			{
				TRET(TCLASS::*method)(P1, P2, P3, P4) = *(TRET(TCLASS::**)(P1, P2, P3, P4))(&callee);
				U8 * frame = stk.CurrentFrame();
				*(Returnval<TRET>::Read(reg, frame)) = (Objectval<TCLASS>::Read(reg, frame)->*method)(
					Parameter<P1>::Read(reg, frame), Parameter<P2>::Read(reg, frame),
					Parameter<P3>::Read(reg, frame), Parameter<P4>::Read(reg, frame));
				return;
			}
		};
		// 4 params, no return value.
		template<typename TCLASS, typename P1, typename P2, typename P3, typename P4>
		struct Caller<void, TCLASS, P1, P2, P3, P4, void, void, void, void, void, void, void, void, void, void, void, void>
		{
			static inline void Invoke(void * callee, GStacker& stk, GRegister& reg) 
			{
				void(TCLASS::*method)(P1, P2, P3, P4) = *(void(TCLASS::**)(P1, P2, P3, P4))(&callee);
				U8 * frame = stk.CurrentFrame();
				Objectval<TCLASS>::Read(reg, frame)->*method(
					Parameter<P1>::Read(reg, frame), Parameter<P2>::Read(reg, frame),
					Parameter<P3>::Read(reg, frame), Parameter<P4>::Read(reg, frame));
				return;
			}
		};

		//--------------------------------------------------------------------------
		// 3 params, have a return value.
		template<typename TRET, typename TCLASS, typename P1, typename P2, typename P3>
		struct Caller<TRET, TCLASS, P1, P2, P3, void, void, void, void, void, void, void, void, void, void, void, void, void>
		{
			static inline void Invoke(void * callee, GStacker& stk, GRegister& reg) 
			{
				TRET(TCLASS::*method)(P1, P2, P3) = *(TRET(TCLASS::**)(P1, P2, P3))(&callee);
				U8 * frame = stk.CurrentFrame();
				*(Returnval<TRET>::Read(reg, frame)) = (Objectval<TCLASS>::Read(reg, frame)->*method)(
					Parameter<P1>::Read(reg, frame), Parameter<P2>::Read(reg, frame),
					Parameter<P3>::Read(reg, frame));
				return;
			}
		};
		// 3 params, no return value.
		template<typename TCLASS, typename P1, typename P2, typename P3>
		struct Caller<void, TCLASS, P1, P2, P3, void, void, void, void, void, void, void, void, void, void, void, void, void>
		{
			static inline void Invoke(void * callee, GStacker& stk, GRegister& reg) 
			{
				void(TCLASS::*method)(P1, P2, P3) = *(void(TCLASS::**)(P1, P2, P3))(&callee);
				U8 * frame = stk.CurrentFrame();
				Objectval<TCLASS>::Read(reg, frame)->*method(
					Parameter<P1>::Read(reg, frame), Parameter<P2>::Read(reg, frame),
					Parameter<P3>::Read(reg, frame));
				return;
			}
		};

		//--------------------------------------------------------------------------
		// 2 params, have a return value.
		template<typename TRET, typename TCLASS, typename P1, typename P2>
		struct Caller<TRET, TCLASS, P1, P2, void, void, void, void, void, void, void, void, void, void, void, void, void, void>
		{
			static inline void Invoke(void * callee, GStacker& stk, GRegister& reg) 
			{
				TRET(TCLASS::*method)(P1, P2) = *(TRET(TCLASS::**)(P1, P2))(&callee);
				U8 * frame = stk.CurrentFrame();
				*(Returnval<TRET>::Read(reg, frame)) = (Objectval<TCLASS>::Read(reg, frame)->*method)(
					Parameter<P1>::Read(reg, frame), Parameter<P2>::Read(reg, frame));
				return;
			}
		};
		// 2 params, no return value.
		template<typename TCLASS, typename P1, typename P2>
		struct Caller<void, TCLASS, P1, P2, void, void, void, void, void, void, void, void, void, void, void, void, void, void>
		{
			static inline void Invoke(void * callee, GStacker& stk, GRegister& reg)
			{
				void(TCLASS::*method)(P1, P2) = *(void(TCLASS::**)(P1, P2))(&callee);
				U8 * frame = stk.CurrentFrame();
				(Objectval<TCLASS>::Read(reg, frame)->*method)(Parameter<P1>::Read(reg, frame), Parameter<P2>::Read(reg, frame));
				return;
			}
		};
		//--------------------------------------------------------------------------
		// 1 param, have a return value.
		template<typename TRET, typename TCLASS, typename P1>
		struct Caller<TRET, TCLASS, P1, void, void, void, void, void, void, void, void, void, void, void, void, void, void, void>
		{
			static inline void Invoke(void * callee, GStacker& stk, GRegister& reg)
			{
				TRET(TCLASS::*method)(P1) = *(TRET(TCLASS::**)(P1))(&callee);
				U8 * frame = stk.CurrentFrame();
				*(Returnval<TRET>::Read(reg, frame)) = (Objectval<TCLASS>::Read(reg, frame)->*method)(Parameter<P1>::Read(reg, frame));
				return;
			}
		};
		// 1 param, no return value.
		template<typename TCLASS, typename P1>
		struct Caller<void, TCLASS, P1, void, void, void, void, void, void, void, void, void, void, void, void, void, void, void>
		{
			static inline void Invoke(void * callee, GStacker& stk, GRegister& reg)
			{
				void(TCLASS::*method)(P1) = *(void(TCLASS::**)(P1))(&callee);
				U8 * frame = stk.CurrentFrame();
				(Objectval<TCLASS>::Read(reg, frame)->*method)(Parameter<P1>::Read(reg, frame));
				return;
			}
		};

		//--------------------------------------------------------------------------
		// no param, have a return value.
		template<typename TRET, typename TCLASS>
		struct Caller<TRET, TCLASS, void, void, void, void, void, void, void, void, void, void, void, void, void, void, void, void>
		{
			static inline void Invoke(void * callee, GStacker& stk, GRegister& reg)
			{
				TRET(TCLASS::*method)() = *(TRET(TCLASS::**)())(&callee);
				U8 * frame = stk.CurrentFrame();
				*(Returnval<TRET>::Read(reg, frame)) = (Objectval<TCLASS>::Read(reg, frame)->*method)();
				return;
			}
		};
		// no param, no return value.
		template<typename TCLASS>
		struct Caller<void, TCLASS, void, void, void, void, void, void, void, void, void, void, void, void, void, void, void, void>
		{
			static inline void Invoke(void * callee, GStacker& stk, GRegister& reg)
			{
				void(TCLASS::*method)() = *(void(TCLASS::**)())(&callee);
				U8 * frame = stk.CurrentFrame();
				(Objectval<TCLASS>::Read(reg, frame)->*method());	
				return;
			}
		};
		//--------------------------------------------------------------------------
	}

	template<typename TRET, typename TCLASS, 
		typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8,
		typename P9, typename P10,typename P11,typename P12,typename P13,typename P14,typename P15,typename P16>
	inline FunctionObject ExportFunction(TRET(TCLASS::*f)(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16))
	{ 
		return FunctionObject(ImplMemberFunctionCaller::
			Caller<TRET, TCLASS, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16>::Invoke, (void*)&f);
	}

	template<typename TRET, typename TCLASS,
		typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8,
		typename P9, typename P10,typename P11,typename P12,typename P13,typename P14,typename P15> 
	inline FunctionObject ExportFunction(TRET(TCLASS::*f)(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15))
	{ 
		return FunctionObject(ImplMemberFunctionCaller::
			Caller<TRET, TCLASS, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15>::Invoke, (void*)&f);
	}

	template<typename TRET, typename TCLASS, 
		typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8,
		typename P9, typename P10,typename P11,typename P12,typename P13,typename P14> 
	inline FunctionObject ExportFunction(TRET(TCLASS::*f)(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14))
	{ 
		return FunctionObject(ImplMemberFunctionCaller::
			Caller<TRET, TCLASS, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14>::Invoke, (void*)&f);
	}

	template<typename TRET, typename TCLASS, 
		typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8,
		typename P9, typename P10,typename P11,typename P12,typename P13> 
	inline FunctionObject ExportFunction(TRET(TCLASS::*f)(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13))
	{ 
		return FunctionObject(ImplMemberFunctionCaller::
			Caller<TRET, TCLASS, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13>::Invoke, (void*)&f);
	}

	template<typename TRET, typename TCLASS, 
		typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8,
		typename P9, typename P10,typename P11,typename P12> 
	inline FunctionObject ExportFunction(TRET(TCLASS::*f)(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12))
	{ 
		return FunctionObject(ImplMemberFunctionCaller::
			Caller<TRET, TCLASS, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12>::Invoke, (void*)&f);
	}

	template<typename TRET, typename TCLASS, 
		typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8,
		typename P9, typename P10,typename P11> 
	inline FunctionObject ExportFunction(TRET(TCLASS::*f)(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11))
	{ 
		return FunctionObject(ImplMemberFunctionCaller::
			Caller<TRET, TCLASS, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11>::Invoke, (void*)&f);
	}

	template<typename TRET, typename TCLASS, 
		typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8,
		typename P9, typename P10> 
	inline FunctionObject ExportFunction(TRET(TCLASS::*f)(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10))
	{ 
		return FunctionObject(ImplMemberFunctionCaller::
			Caller<TRET, TCLASS, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10>::Invoke, (void*)&f);
	}

	template<typename TRET, typename TCLASS, 
		typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8, typename P9>
	inline FunctionObject ExportFunction(TRET(TCLASS::*f)(P1, P2, P3, P4, P5, P6, P7, P8, P9))
	{
		return FunctionObject(ImplMemberFunctionCaller
			::Caller<TRET, TCLASS, P1, P2, P3, P4, P5, P6, P7, P8, P9>::Invoke, (void*)&f);
	}

	template<typename TRET, typename TCLASS, 
		typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8>
	inline FunctionObject ExportFunction(TRET(TCLASS::*f)(P1, P2, P3, P4, P5, P6, P7, P8))
	{
		return FunctionObject(ImplMemberFunctionCaller::Caller<TRET, TCLASS, P1, P2, P3, P4, P5, P6, P7, P8>::Invoke, (void*)&f);
	}

	template<typename TRET, typename TCLASS, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7>
	inline FunctionObject ExportFunction(TRET(TCLASS::*f)(P1, P2, P3, P4, P5, P6, P7))
	{
		return FunctionObject(ImplMemberFunctionCaller::Caller<TRET, TCLASS, P1, P2, P3, P4, P5, P6, P7>::Invoke, (void*)&f);
	}

	template<typename TRET, typename TCLASS, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6>
	inline FunctionObject ExportFunction(TRET(TCLASS::*f)(P1, P2, P3, P4, P5, P6))
	{
		return FunctionObject(ImplMemberFunctionCaller::Caller<TRET, TCLASS, P1, P2, P3, P4, P5, P6>::Invoke, (void*)&f);
	}

	template<typename TRET, typename TCLASS, typename P1, typename P2, typename P3, typename P4, typename P5>
	inline FunctionObject ExportFunction(TRET(TCLASS::*f)(P1, P2, P3, P4, P5))
	{
		return FunctionObject(ImplMemberFunctionCaller::Caller<TRET, TCLASS, P1, P2, P3, P4, P5>::Invoke, (void*)&f);
	}

	template<typename TRET, typename TCLASS, typename P1, typename P2, typename P3, typename P4>
	inline FunctionObject ExportFunction(TRET(TCLASS::*f)(P1, P2, P3, P4)) 
	{
		return FunctionObject(ImplMemberFunctionCaller::Caller<TRET, TCLASS, P1, P2, P3, P4>::Invoke, (void*)&f);
	}

	template<typename TRET, typename TCLASS, typename P1, typename P2, typename P3>
	inline FunctionObject ExportFunction(TRET(TCLASS::*f)(P1, P2, P3))
	{
		return FunctionObject(ImplMemberFunctionCaller::Caller<TRET, TCLASS, P1, P2, P3>::Invoke, (void*)&f);
	}

	template<typename TRET, typename TCLASS, typename P1, typename P2>
	inline FunctionObject ExportFunction(TRET(TCLASS::*f)(P1, P2))
	{
		return FunctionObject(ImplMemberFunctionCaller::Caller<TRET, TCLASS, P1, P2>::Invoke, (void*)&f);
	}

	template<typename TRET, typename TCLASS, typename P1>
	inline FunctionObject ExportFunction(TRET(TCLASS::*f)(P1))
	{
		return FunctionObject(ImplMemberFunctionCaller::Caller<TRET, TCLASS, P1>::Invoke, (void*)&f);
	}

	template<typename TRET, typename TCLASS>
	inline FunctionObject ExportFunction(TRET(TCLASS::*f)())
	{
		return FunctionObject(ImplMemberFunctionCaller::Caller<TRET, TCLASS>::Invoke, (void*)&f);
	}

	/////////////////////////////////////////////////////////////////////
	// Template: ExportFunction, for global functions.
	// Return: FunctionObject
	/////////////////////////////////////////////////////////////////////
#	define CALLCONV __cdecl
#	define CALLERNS ImplGlobalFunctionCaller_cdecl
#	include "GFunction.inl"
#	undef CALLERNS
#	undef CALLCONV
#	define CALLCONV __stdcall
#	define CALLERNS ImplGlobalFunctionCaller_stdcall
#	include "GFunction.inl"
#	undef CALLERNS
#	undef CALLCONV
#	define CALLCONV __fastcall
#	define CALLERNS ImplGlobalFunctionCaller_fastcall
#	include "GFunction.inl"
#	undef CALLERNS
#	undef CALLCONV

}

#endif	//ifndef GMACHINE_HEADER_GFUNCTION_H
